/*
 * config_factory.c
 *
 *  Created on: 2016年6月21日
 *      Author: fqk
 */
#include "config_factory.h"



huidu_limit_info_t 	*g_huidu_config	=NULL;

ngx_log_t 			*g_log 			= NULL;

pthread_t			 g_config_thread_tid = 0;
ngx_http_huidu_redis_address_t *g_redis_addr=NULL;
ngx_uint_t			 g_redis_count=0;



//static void * 			config_get_thread();

/*
 *
 * */

#define DEBUG_LOG(LEVEL,str) log_append_to_file(LEVEL, str,__FILE__,__LINE__ );

void log_append_to_file(ngx_uint_t level,char* str,char* sourceFile,int fileLine)
{
	if(g_log == NULL) return;
	ngx_log_error(level, g_log, 0,"%s(:%d):%s\r\n", sourceFile,fileLine, str);

}



static int check_config(huidu_info static_info){
	if(static_info.ip_list.size == 0 &&
			static_info.user_id_list.size == 0 &&
			static_info.appid_list.size == 0 &&
			static_info.bbversion_list.size == 0)
		return -1;

	return 0;
}


static void copy_static_config(huidu_info static_info){
	huidu_limit_info_t 	*p_huidu_config =NULL;
	huidu_limit_info_t 	*huidu_config_tmp;

	huidu_config_tmp = g_huidu_config;
	p_huidu_config =  malloc(sizeof(huidu_limit_info_t));

	tran_to_huidu_limit_info(static_info, p_huidu_config);
	g_huidu_config = p_huidu_config;
	if(huidu_config_tmp !=  NULL){
		free_huidu_limit_info(huidu_config_tmp);
		free(huidu_config_tmp);
	}
}

static void init_limit_info(huidu_limit_info_t 	* p){

	if(p == NULL) return ;

	p->appid_list.cnt = 0;
	p->appid_list.data = NULL;

	p->ip_list.cnt = 0;
	p->ip_list.data = NULL;

	p->user_id_list.cnt = 0;
	p->user_id_list.data = NULL;

	p->bbversion_list.cnt = 0;
	p->bbversion_list.data = NULL;
}

static void  copy_null_config(){

	huidu_limit_info_t 	*p_huidu_config =NULL;
	huidu_limit_info_t 	*huidu_config_tmp;

	if(g_huidu_config == NULL)
		return ;
	else if(g_huidu_config->appid_list.cnt == 0 &&
			g_huidu_config->ip_list.cnt == 0 &&
			g_huidu_config->user_id_list.cnt == 0 &&
			g_huidu_config->bbversion_list.cnt == 0){
		return ;
	}


	huidu_config_tmp = g_huidu_config;

	p_huidu_config =  malloc(sizeof(huidu_limit_info_t));
	init_limit_info(p_huidu_config);
	g_huidu_config = p_huidu_config;
	if(huidu_config_tmp !=  NULL){
		free_huidu_limit_info(huidu_config_tmp);
		free(huidu_config_tmp);
	}
}


void
config_get_func(){


	 char log_buf[128];

	 void 		* 	redis_connetion = NULL;
	 huidu_info         static_info;
	 pid_t ngx_pid_u;
	 ngx_pid_u = getpid();


	 sprintf(log_buf,">>>>>>>>start get config, pid = %d!\n",ngx_pid_u);
	 DEBUG_LOG(NGX_LOG_ERR,log_buf);

	 redis_connetion = connet_to_redis();

	 if(NULL == redis_connetion){
		DEBUG_LOG(NGX_LOG_ERR,">>>>>>>>connet redis error!\n");
		return ;
	 }
	 memset(&static_info, 0, sizeof(huidu_info));

	 DEBUG_LOG(NGX_LOG_INFO,">>>>>>>>redis_connetion  success!\n");
	 get_huidu_info(redis_connetion, &static_info);

	 DEBUG_LOG(NGX_LOG_INFO,">>>>>>>>get_huidu_info  success!\n");

	 if(check_config(static_info) == 0){
		//拷贝配置文件
		 copy_static_config(static_info);
	 }
	 else {
		 //获取数据为空
		 copy_null_config();
	 }
	free_huidu_info(&static_info);

	sprintf(log_buf,"g_huidu_config = %p",g_huidu_config);
	DEBUG_LOG(NGX_LOG_INFO,log_buf);

	free_connettion(redis_connetion);
	return ;
}


void * config_get_thread(void *arg){

	while(1){
		config_get_func();

		sleep(SLEEP_TIME);
	}

}


int start_config_thread(ngx_log_t *log){

	int         	err;
	pthread_t   	tid = 0;
	g_log = log;
	err = pthread_create(&tid, NULL, config_get_thread, NULL);
	if (err != 0)  {
		DEBUG_LOG(NGX_LOG_ERR,"ERROR！can't create thread:, return -1\n");
		return -1;
	}
	return 0;
}


void tran_to_huidu_str_array(str_array src_array, huidu_str_array_t *des_array){

  ngx_uint_t i = 0;
  des_array->data = malloc( sizeof(ngx_str_t) *(src_array.size));
  des_array->cnt = src_array.size;

  for(i = 0; i< des_array->cnt; i++){
    des_array->data[i].data = malloc( src_array.data[i].len);
    des_array->data[i].len = src_array.data[i].len;
    memcpy(des_array->data[i].data, src_array.data[i].data,  src_array.data[i].len);
  }

}

void tran_to_huidu_limit_info(huidu_info src_info, huidu_limit_info_t *des_info){

      tran_to_huidu_str_array(src_info.ip_list, &(des_info->ip_list));
      tran_to_huidu_str_array(src_info.user_id_list, &(des_info->user_id_list));
      tran_to_huidu_str_array(src_info.appid_list, &(des_info->appid_list));
      tran_to_huidu_str_array(src_info.bbversion_list, &(des_info->bbversion_list));

}

void  free_huidu_str_array(huidu_str_array_t  *array){
    if(NULL == array) return ;
     ngx_uint_t i =0;
     for(i = 0 ; i <array->cnt; i ++){
       free(array->data[i].data);
        array->data[i].data = NULL;
        array->data[i].len = 0;
    }
    free(array->data);
     array->data = NULL;
     array->cnt = 0;

}

void free_huidu_limit_info(huidu_limit_info_t *limit_info){
    if(NULL == limit_info) return ;

    free_huidu_str_array(&(limit_info->ip_list));
    free_huidu_str_array(&(limit_info->user_id_list));
    free_huidu_str_array(&(limit_info->appid_list));
    free_huidu_str_array(&(limit_info->bbversion_list));

}
